package com.aegis.manage.service.auth.app;

import cn.hutool.core.collection.CollectionUtil;
import com.aegis.common.mybatis.model.PageResult;
import com.aegis.common.redis.annotation.RedisDelayDel;
import com.aegis.common.redis.annotation.RedisDelayDelKey;
import com.aegis.common.redis.util.RedisUtil;
import com.aegis.common.utils.AssertUtil;
import com.aegis.core.manager.AegisAppManager;
import com.aegis.manage.api.dto.QueryAppInfoPageDTO;
import com.aegis.manage.api.dto.SysApiPermissionDTO;
import com.aegis.manage.api.request.*;
import com.aegis.manage.api.vo.AppDetailVO;
import com.aegis.manage.api.vo.AppGroupVO;
import com.aegis.manage.api.vo.AppInfoVO;
import com.aegis.manage.api.vo.GenerateAppVO;
import com.aegis.manage.constants.RedisConstants;
import com.aegis.manage.mapper.AuthApiPermissionGroupMapper;
import com.aegis.manage.mapper.AuthAppPermissionAssignmentMapper;
import com.aegis.manage.model.dos.AuthApiPermissionGroup;
import com.aegis.manage.model.dos.AuthAppPermissionAssignment;
import com.aegis.manage.threadpool.RedisDelThreadPool;
import com.aegis.manage.utils.PasswordUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.aegis.common.mybatis.base.BaseServiceImpl;
import com.aegis.manage.mapper.AuthAppMapper;
import com.aegis.manage.model.dos.AuthApp;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Optional;
import java.util.function.Supplier;

/**
 * @Author wuweixin
 *
 * @Version 1.0
 * @Descritube
 */
@Service
public class AuthAppServiceImpl extends BaseServiceImpl<AuthAppMapper, AuthApp> implements AuthAppService {

    @Autowired
    private AuthAppMapper authAppMapper;

    @Autowired
    private AuthApiPermissionGroupMapper authApiPermissionGroupMapper;

    @Autowired
    private AuthAppPermissionAssignmentMapper authAppPermissionAssignmentMapper;


    @Override
    public AuthApp selectAppByAppId(String appId) {
        return selectOne(new LambdaQueryWrapper<AuthApp>().eq(AuthApp::getAppId, appId));
    }

    @Override
    public List<AuthApp> selectAllApps() {
        return selectList();
    }

    @Override
    public List<SysApiPermissionDTO> selectAppApiPermissions(String appId) {
        return authAppMapper.selectAppApiPermissions(appId);
    }

    @Override
    public List<SysApiPermissionDTO> selectAppApiGroupPermissions(String appId) {
        return authAppMapper.selectAppApiGroupPermissions(appId);
    }


    @Override
    public GenerateAppVO generateApp(GenerateAppRequest request) {
        Long l = getBaseMapper().selectCount(new LambdaQueryWrapper<AuthApp>()
                .eq(AuthApp::getAppName, request.getName()));
        AssertUtil.operateFailed(l > 0, "应用名已存在");
        AuthApp authApp = new AuthApp();
        authApp.setAppName(request.getName());
        authApp.setRemark(request.getRemark());
        authApp.setAppId(PasswordUtil.generateAppId());
        authApp.setAppSecret(PasswordUtil.generateAppSecret());
        save(authApp);
        GenerateAppVO result = new GenerateAppVO();
        result.setId(authApp.getId());
        result.setAppId(authApp.getAppId());
        return result;
    }

    @Override
    public void updateApp(UpdateAppRequest request) {
        AuthApp authApp = getById(request.getId());
        AssertUtil.operateFailed(authApp == null, "不存在的应用");
        AssertUtil.operateFailed("aegis".equals(request.getId()) &&
                        request.getStatus() != null && request.getStatus() != 0,
                "管理平台禁止禁用");
        BeanUtils.copyProperties(request, authApp);
        authApp.updateById();
    }

    @Override
    public PageResult<AppInfoVO> queryAppInfoPage(QueryAppInfoPageRequest request) {
        QueryAppInfoPageDTO queryAppInfoPageDTO = new QueryAppInfoPageDTO();
        queryAppInfoPageDTO.setKeywords(request.getKeywords());
        IPage<AppInfoVO> appInfoVOIPage =
                getBaseMapper().queryAppInfoPage(new Page<>(request.getCurrent(), request.getSize()),
                        queryAppInfoPageDTO);
        return PageResult.exchange(appInfoVOIPage);
    }

    @Override
    public AppDetailVO selectAppDetailById(String id) {
        return getBaseMapper().selectAppDetailById(id);
    }

    @Override
    public void delAppById(String id) {
        AssertUtil.operateFailed("aegis".equals(id), "管理平台禁止删除");
        AuthApp authApp = getBaseMapper().selectById(id);
        AegisAppManager.removeApp(authApp.getAppId());
        AssertUtil.operateFailed(getBaseMapper().deleteById(id) <= 0, "删除失败");
    }

    @Override
    public PageResult<AppGroupVO> queryAppGroupPage(QueryAppGroupPageRequest request) {
        IPage<AppGroupVO> appGroupVOIPage = authAppMapper.queryAppGroupPage(new Page<>(request.getCurrent(), request.getSize()), request.getId(), request.getKeywords());
        return PageResult.exchange(appGroupVOIPage);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void bindAppGroup(BindAppGroupRequest request) {
        Long l = authApiPermissionGroupMapper.selectCount(new LambdaQueryWrapper<AuthApiPermissionGroup>()
                .in(AuthApiPermissionGroup::getId, request.getGroupId()));
        AssertUtil.operateFailed(l < request.getGroupId().size(), "部分权限组不存在");
        AssertUtil.operateFailed(getBaseMapper().selectById(request.getSysAppId()) == null, "不存在的应用");
        AssertUtil.operateFailed(authAppPermissionAssignmentMapper.selectCount(new LambdaQueryWrapper<AuthAppPermissionAssignment>()
                .eq(AuthAppPermissionAssignment::getSysAppId, request.getSysAppId())
                .in(AuthAppPermissionAssignment::getPermissionGroupId, request.getGroupId())) > 0, "部分权限组已被绑定");
        for (String s : request.getGroupId()) {
            AuthAppPermissionAssignment authAppPermissionAssignment = new AuthAppPermissionAssignment();
            authAppPermissionAssignment.setSysAppId(request.getSysAppId());
            authAppPermissionAssignment.setPermissionGroupId(s);
            authAppPermissionAssignment.insert();
        }
    }

    @Override
    public void delBindGroup(String id) {
        AssertUtil.operateFailed(authAppPermissionAssignmentMapper.deleteById(id) <= 0, "删除失败");
    }


}
